package com.wzcl.app.handler;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.RVO;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.xml.bind.ValidationException;
import java.util.List;

/**
 * 全局错误拦截器
 */
@Log4j2
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public RVO<String> exceptionHandler(Exception e) {
        //系统内部
        if (e instanceof BusinessException) {
            BusinessException businessException = (BusinessException) e;
            return new RVO<String>(businessException.getCode(), businessException.getMessage());
        }else if(e instanceof BindException){
            List<ObjectError> list = ((BindException) e).getAllErrors();
            StringBuilder sb = new StringBuilder("参数错误：[");
            for (ObjectError item : list) {
                sb.append(item.getDefaultMessage()).append(',');
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append(']');
            return RVO.error(sb.toString());
        }else if(e instanceof MissingServletRequestParameterException) {
            log.error("缺少请求参数：{}", e.getMessage());
            return RVO.error("缺少请求参数");
        }else if(e instanceof HttpMessageNotReadableException) {
            log.error("参数解析失败：{}", e.getMessage());
            return RVO.error("参数解析失败");
        }else if(e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException e1 = (MethodArgumentNotValidException) e;
            BindingResult result = e1.getBindingResult();
            FieldError error = result.getFieldError();
            if (error != null) {
                String field = error.getField();
                String code = error.getDefaultMessage();
                return RVO.error("参数验证失败:"+String.format("%s:%s", field, code));
            }
            return RVO.error("参数验证失败");
        }else if(e instanceof ValidationException) {
            log.error("参数验证失败：{}", e.getMessage());
            return RVO.error("参数验证失败");
        }else if(e instanceof NoHandlerFoundException) {
            return RVO.error("Not Found "+e.getMessage());
        }else if(e instanceof HttpRequestMethodNotSupportedException) {
            return RVO.error("不支持当前请求方法:"+e.getMessage());
        }else{
            e.printStackTrace();
            return RVO.error(CodeMsg.SYSTEM_ERR);
        }
    }

}
